package com.cwj.common.utils;

import com.cwj.common.domain.film;
import org.apache.commons.beanutils.BeanUtils;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.servlet.http.Cookie;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class utils {
    /**
     * 获取本机ip地址 windows操作系统 linux操作系统
     *
     */
    public static String getIpAddress()  {

        try {
            Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            InetAddress ip ;
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = allNetInterfaces.nextElement();
                if (!netInterface.isLoopback() && !netInterface.isVirtual() && netInterface.isUp()) {
                    Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
                    while (addresses.hasMoreElements()) {
                        ip = addresses.nextElement();
                        if (ip instanceof Inet4Address) {
                            return ip.getHostAddress();
                        }
                    }
                }
            }
        } catch (SocketException e) {
            System.out.println("异常"+e);
        }
        return "";
    }
    /**
     * 裁剪图片
     * @author     https://www.cnblogs.com/gavinYang/p/11197756.html
     */
    public  static void cut(String srcPath, String subPath, int width, int height,List<Closeable> closeableList) throws IOException {
        //读取图片文件

        FileInputStream is  = new FileInputStream(srcPath);
       closeableList= closeableList==null ? new ArrayList<>() :closeableList;
        closeableList.add(is);
            /*
              返回包含所有当前已注册 ImageReader 的 Iterator，这些 ImageReader
              声称能够解码指定格式。参数：formatName - 包含非正式格式名称 .
             （例如 "jpeg" 或 "tiff"）等。
             */
            String suffix = srcPath.substring(srcPath.lastIndexOf(".")+1);
            Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(suffix);
            ImageReader reader = it.next();

            //获取图片流
        ImageInputStream iis = ImageIO.createImageInputStream(is);
        closeableList.add(iis);
            /**//*
             * <p>iis:读取源.true:只向前搜索 </p>.将它标记为‘只向前搜索’。
             * 此设置意味着包含在输入源中的图像将只按顺序读取，可能允许 reader
             *  避免缓存包含与以前已经读取的图像关联的数据的那些输入部分。
             */
            reader.setInput(iis,true) ;
            /*
              <p>描述如何对流进行解码的类<p>.用于指定如何在输入时从 Java Image I/O
              框架的上下文中的流转换一幅图像或一组图像。用于特定图像格式的插件
              将从其 ImageReader 实现的 getDefaultReadParam 方法中返回
              ImageReadParam 的实例。
             */
            ImageReadParam param = reader.getDefaultReadParam();

            /**//*
             * 图片裁剪区域。Rectangle 指定了坐标空间中的一个区域，通过 Rectangle 对象
             * 的左上顶点的坐标（x，y）、宽度和高度可以定义这个区域。
             */
            Rectangle rect = new Rectangle(0, 0, width, height);


            //提供一个 BufferedImage，将其用作解码像素数据的目标。
            param.setSourceRegion(rect);

            /**//*
             * 使用所提供的 ImageReadParam 读取通过索引 imageIndex 指定的对象，并将
             * 它作为一个完整的 BufferedImage 返回。
             */
        BufferedImage bi =  reader.read(0,param);

            //保存新图片
            ImageIO.write(bi, suffix, new File(subPath));
        }
    /**
     *  打包为 zip 文件
     * @param file 待打包的文件
     * @param zos zip zip输出流
     */
    public static void doZip(File file, ZipOutputStream zos,List<Closeable> list) throws IOException {

                //假设是文件，写入到 zip 流中
                BufferedInputStream   bis = new BufferedInputStream(new FileInputStream(file));
                list.add(bis);
                zos.putNextEntry(new ZipEntry(file.getName()));
                    byte[] buffer = new byte[1024];
                    int r ;
                    while ((r = bis.read(buffer)) != -1) {
                        zos.write(buffer, 0, r);
                    }

            }
    public static void GetFilmPictList(List<film> films,int w, int h,String serverPath) throws InvocationTargetException, IllegalAccessException {
        File[] files = new File(serverPath+"pict\\_" + w + "x" + h).listFiles();
        for (film film : films) {
            String title = film.getTitle();
            assert files != null;
            File f = Arrays.stream(files).filter(file -> file.getName().substring(0, file.getName().lastIndexOf(".")).equals(title)).collect(Collectors.toList()).get(0);
            String substring = f.getAbsolutePath().substring(serverPath.length());
            BeanUtils.setProperty(film,"_"+w+"x"+h+"pict",substring);

        }
    }

    /**
     * 从cookie数组中获取对应name的cookie的value
     * @return  如果name数组的个数和map元素的个数一致  则返回map集合 其他情况返回null
     */
    public static Map<String,String> GetCookieValueByCookieName(Cookie[] cookies,String... names){
        HashMap<String, String> map = cookies!=null&&cookies.length>0&&cookies.length>=names.length
                                                ? new HashMap<>() : null;
        if(map==null){
            return null;
        }
        List<String> nameList = Arrays.asList(names);
        Arrays.stream(cookies).forEach(cookie -> {
                if(nameList.contains(cookie.getName())){
                    map.put(cookie.getName(), URLDecoder.decode(cookie.getValue(), StandardCharsets.UTF_8));
                }
        });
        return  map;

    }

    /**
     * 从cookie中获取user转成map集合
     * @return map集合 key-属性名 value-属性值
     */
    public static Map<String,String> GetUserByCookie(Cookie[] cookies){
        Map<String, String> userMap = utils.GetCookieValueByCookieName(cookies, "UserName", "password");
        HashMap<String, String> map =new HashMap<>();
        if(userMap!=null&&userMap.size()==2){
            for (String key: userMap.keySet()) {
                map.put(key.toLowerCase(),userMap.get(key));
            }
        }else {
            map.put("username","");
            map.put("password","");
        }
        return  map;
    }
}
